/*******************************************************
> Copyright (C) 2024 ==IOT== All rights reserved.
> File Name: inherit.cpp
> Author: IOT
> Website:www.slq.org
> Created Time: 2024年10月24日 星期四 10时40分12秒
***************************************************/

#include <iostream>
using namespace std;

class Base { // 定义一个基类(父类)
	int len = 3;
protected:      // 体现封装性，使类外不能访问，可以使派生类直接使用
	int m = 10;
public:
	Base() : len(0), m(0)
	{
		cout << "调用基类无参数构造" << endl;
	}
	
	Base(int _m, int _len) : len(_len), m(_m) // 当我们提供了带参数构造后，编译器没有提供默认构造
	{
		cout << "调用基类双参数构造" << endl;
	}
	
	Base(const Base& obj)
	{
		cout << "基类拷贝构造" << endl;
	}
	
	void operator=(const Base& obj)
	{
		cout << "调用基类的 = 重载" << endl;
	}
	
	~Base()
	{
		cout << "调用基类析构函数" << endl;
	}
	
	int getLen()
	{
		return len;
	}
	void show()
	{
		cout << "m = " << m << endl;
	}
};

// 派生类无法继承基类的构造函数
class Derived : public Base {	// 由基类派生出新类，派生类继承基类，改造基类，并增加自己的特性和行为
	int n = 5;
	public:
		Derived() : Base() // 类没有显式设计时构造函数时，编译器提供无参的默认构造
		{
			cout << "调用派生类无参构造" << endl;
		}
		
		Derived(const Derived& obj) // 派生类没有显示添加拷贝构造时，编译器主动调用基类拷贝构造(编译器默认行为)
		{
			cout << "调用派生类拷贝构造" << endl;
		}
		
		#if 1
		void operator=(const Derived& obj)
		{
			cout << "调用派生类的 = 重载" << endl;
		}
		#endif
		
		~Derived()
		{
			cout << "调用派生类析构" << endl;
		}
		
		void set(int n)
		{
			this->n = n;
		}
		
		void show()
		{
			cout << "m = " << m << ",n = " << n << ", len = " << getLen() << endl; // 派生类虽然继承了成员变量m，但是不能直接访问
		}
};

int main(int argc,const char* argv[])
{
	Base base;
	Base base2(2,3);
	//base.m = 0; // 类外不能访问非公有的成员变量
	cout << "base size:" << sizeof(base) << endl;
	cout << "基类(旧类，父类):";
	base.show();
	
	cout << "** 实例化派生类对象 **" << endl;
	Derived der;
	cout << "derived size:" << sizeof(der) << endl;
	cout << "派生类(新类，子类):";
	der.show();
	der.set(15);
	der.show(); // 先调用自己的show,再调用基类的show
	
	//Derived der2(2, 3); // error
	Derived der2(der); // 实例化一个类对象时，用另一个对象对其赋初始值，调用拷贝构造
	
	der = der2;
	
    return 0;
}
